
#ifndef __SPHERE_H__
#define __SPHERE_H__

#include "hittable.hh"
#include "vec3.hh"

class sphere : public hittable {
	public : 
		point3 center;
		double radius;
		shared_ptr<material> pmat;

	public : 
		sphere() {}
		sphere(point3 c, double r, shared_ptr<material> p) : center{c}, radius{r}, pmat{p} {}

		virtual bool hit(const ray& r, double min_t, double max_t, hit_record& rec) const override;
};

bool sphere::hit(const ray& r, double min_t, double max_t, hit_record& rec) const {
	vec3 oc = r.origin() - center;
	auto a = dot(r.direction(), r.direction());
	auto b = 2.0 * dot(oc, r.direction());
	auto c = dot(oc, oc) - radius * radius;
	auto dis = b * b - 4 * a * c;

	if (dis < 0) { return false; }
	
	auto sqrtd = std::sqrt(dis);
	auto root = (-b - sqrtd) / (2 * a);
	if (root < min_t || max_t < root) { 
		root = (-b + sqrtd) / (2 * a);
		if (root < min_t || max_t < root) { 
			return false;
		}
	}

	rec.t = root;
	rec.point = r.at(rec.t);

	vec3 outward_normal = (rec.point - center) / radius;
	rec.set_face_normal(r, outward_normal);
	rec.pmat = pmat;

	return true;
}

#endif
